package com.xian.wsim.util;

import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorOutputStream;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.apache.commons.compress.compressors.CompressorInputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

@Component
public class CompressionUtil {

    public String compress(String data) throws CompressorException {
        if (data == null || data.isEmpty()) {
            return data;
        }

        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
             CompressorOutputStream compressorOutputStream = new CompressorStreamFactory()
                     .createCompressorOutputStream(CompressorStreamFactory.BZIP2, byteArrayOutputStream)) {

            compressorOutputStream.write(data.getBytes(StandardCharsets.UTF_8));
            //compressorOutputStream.finish();
            compressorOutputStream.close();

            return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
        } catch (IOException e) {
            throw new RuntimeException("Failed to compress data", e);
        }
    }

    public String decompress(String compressedData) throws CompressorException {
        if (compressedData == null || compressedData.isEmpty()) {
            return compressedData;
        }

        try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(Base64.getDecoder().decode(compressedData));
             CompressorInputStream compressorInputStream = new CompressorStreamFactory()
                     .createCompressorInputStream(CompressorStreamFactory.BZIP2, byteArrayInputStream)) {

            return convertStreamToString(compressorInputStream);
        } catch (IOException e) {
            throw new RuntimeException("Failed to decompress data", e);
        }
    }

    public String convertStreamToString(InputStream inputStream) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, length);
        }
        return outputStream.toString(StandardCharsets.UTF_8.name());
    }
}